home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
lang
/
PPCsmalltalk.lha
/
PPCSmallTalk
/
sources
/
primitive.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-10-19
|
34KB
|
1,387 lines
/*
Little Smalltalk
Primitive manager
timothy a. budd
10/84
hashcode code written by Robert McConeghy
(who also wrote classes Dictionary, et al).
*/
/*
The source code for the Little Smalltalk System may be freely
copied provided that the source of all files is acknowledged
and that this condition is copied with each file.
The Little Smalltalk System is distributed without responsibility
for the performance of the program and without any guarantee of
maintenance.
All questions concerning Little Smalltalk should be addressed to:
Professor Tim Budd
Department of Computer Science
The University of Arizona
Tucson, Arizona
85721
USA
*/
# include "object.h"
# ifdef CURSES
# include <curses.h>
# endif
# include <stdio.h>
# include <ctype.h>
# include <math.h>
# include <errno.h>
# include "drive.h"
# include "interp.h"
# include "process.h"
# include "block.h"
# include "string.h"
# include "symbol.h"
# include "number.h"
# include "file.h"
# include "byte.h"
# include "primitive.h"
extern int errno;
extern int prntcmd;
extern double modf();
extern long time();
extern char *ctime();
extern object *lookup_class();
extern process *runningProcess;
extern int responds_to(), generality();
extern class *mk_class();
extern object *o_object, *o_true, *o_false, *o_nil, *o_number, *o_magnitude;
object *primitive(primnumber, numargs, args)
int primnumber, numargs;
object **args;
{ object *resultobj;
object *leftarg, *rightarg, *fnd_class(), *fnd_super();
int leftint, rightint, i, j;
double leftfloat, rightfloat;
long clock;
char *leftp, *rightp, *errp;
class *aClass;
bytearray *byarray;
struct file_struct *phil;
int opnumber = primnumber % 10;
char strbuffer[300], tempname[100];
errno = 0;
/* first do argument type checking */
switch(i = (primnumber / 10)) {
case 0: /* misc operations */
if (opnumber <= 5 && numargs != 1) goto argcerror;
leftarg = args[0];
break;
case 1: /* integer operations */
case 2:
if (numargs != 2) goto argcerror;
rightarg = args[1];
if (! is_integer(rightarg)) goto argterror;
rightint = int_value(rightarg);
case 3:
if (i == 3 && opnumber && numargs != 1)
goto argcerror;
leftarg = args[0];
if (! is_integer(leftarg)) goto argterror;
leftint = int_value(leftarg);
break;
case 4: /* character operations */
if (numargs != 2) goto argcerror;
rightarg = args[1];
if (! is_character(rightarg)) goto argterror;
rightint = int_value(rightarg);
case 5:
if (i == 5 && numargs != 1) goto argcerror;
leftarg = args[0];
if (! is_character(leftarg)) goto argterror;
leftint = int_value(leftarg);
break;
case 6: /* floating point operations */
if (numargs != 2) goto argcerror;
rightarg = args[1];
if (! is_float(rightarg)) goto argterror;
rightfloat = float_value(rightarg);
case 7:
if (i == 7 && numargs != 1) goto argcerror;
case 8:
if (i == 8 && opnumber < 8 && numargs != 1)
goto argcerror;
leftarg = args[0];
if (! is_float(leftarg)) goto argterror;
leftfloat = float_value(leftarg);
break;
case 9: /* symbol operations */
leftarg = args[0];
if (! is_symbol(leftarg)) goto argterror;
leftp = symbol_value(leftarg);
break;
case 10: /* string operations */
if (numargs < 1) goto argcerror;
leftarg = args[0];
if (! is_string(leftarg)) goto argterror;
leftp = string_value(leftarg);
if (opnumber && opnumber <= 3) {
if (numargs != 2) goto argcerror;
rightarg = args[1];
if (! is_string(rightarg)) goto argterror;
rightp = string_value(rightarg);
}
else if ((opnumber >= 4) && (opnumber <= 6)) {
if (numargs < 2) goto argcerror;
if (! is_integer(args[1])) goto argterror;
i = int_value(args[1])-1;
if ((i < 0) || (i >= strlen(leftp)))
goto indexerror;
}
else if ((opnumber >= 7) && (numargs != 1))
goto argcerror;
break;
case 11: /* misc operations */
if ((opnumber == 1) || (opnumber == 2)) {
if (is_bltin(args[0])) goto argterror;
if (numargs < 2) goto argcerror;
if (! is_integer(args[1])) goto argterror;
i = int_value(args[1]);
if (i < 1 || i > args[0]->size)
goto indexerror;
}
else if ((opnumber >= 4) && (opnumber <= 6)) {
if (numargs != 1) goto argcerror;
if (! is_integer(args[0])) goto argterror;
i = int_value(args[0]);
if (i < 0) goto indexerror;
}
else if (opnumber >= 7) {
if (numargs < 1) goto argcerror;
if (! is_bytearray(args[0])) goto argterror;
byarray = (bytearray *) args[0];
if (opnumber >= 8) {
if (numargs < 2) goto argcerror;
if (! is_integer(args[1]))
goto argterror;
i = int_value(args[1]) - 1;
if (i < 0 || i >= byarray->a_bsize)
goto indexerror;
}
}
break;
case 12: /* string i/o operations */
if (opnumber < 6) {
if (numargs < 1) goto argcerror;
leftarg = args[0];
if (! is_string(leftarg)) goto argterror;
leftp = string_value(leftarg);
}
break;
case 13: /* operations on file */
if (numargs < 1) goto argcerror;
if (! is_file(args[0])) goto argterror;
phil = (struct file_struct *) args[0];
if (opnumber && (phil->fp == (FILE *) NULL)) {
errp = "file must be open for operation";
goto return_error;
}
break;
case 15: /* operations on classes */
if (opnumber < 3 && numargs != 1) goto argcerror;
if (! is_class(args[0])) goto argterror;
aClass = (class *) args[0];
break;
# ifdef PLOT3
case 17: /* plot(3) interface */
if (opnumber && opnumber <= 3) {
if (numargs != 2) goto argcerror;
if ((! is_integer(args[0])) ||
(! is_integer(args[1])))
goto argterror;
leftint = int_value(args[0]);
rightint = int_value(args[1]);
}
else if ((opnumber == 6) || (opnumber == 7)) {
if (numargs != 4) goto argcerror;
for (i = 0; i < 4; i++)
if (! is_integer(args[i]))
goto argterror;
leftint = int_value(args[0]);
rightint = int_value(args[1]);
i = int_value(args[2]);
j = int_value(args[3]);
}
else if (opnumber >= 8) {
if (numargs != 1) goto argcerror;
if (! is_string(args[0])) goto argterror;
leftp = string_value(args[0]);
}
break;
# endif
}
/* now do operation */
switch(primnumber) {
case 1: /* class of object */
resultobj = fnd_class(args[0]);
if (resultobj) goto return_obj;
else goto return_nil;
case 2: /* get super_object */
resultobj = fnd_super(args[0]);
if (resultobj) goto return_obj;
else goto return_nil;
case 3: /* see if class responds to new */
leftint = 0;
if (! is_class(args[0])) goto return_boolean;
leftint = responds_to("new", (class *) args[0]);
goto return_boolean;
case 4: /* compute size of object */
leftint = args[0]->size;
goto return_integer;
case 5: /* return hashnum of object */
if (is_integer(leftarg))
leftint = int_value(leftarg);
else if (is_character(leftarg))
leftint = int_value(leftarg);
else if (is_symbol(leftarg))
leftint = (int) symbol_value(leftarg);
else if (is_string(leftarg)) {
leftp = string_value(leftarg);
leftint = 0;
for(i = 0; *leftp != 0; leftp++){
leftint += *leftp;
i++;
if(i > 5)
break;
}
}
else /* for all other objects return address */
leftint = (int) &leftarg;
if (leftint < 0)
leftint = -leftint;
goto return_integer;
case 6: /* built in object type testing */
if (numargs != 2) goto argcerror;
leftint = (args[0]->size == args[1]->size);
goto return_boolean;
case 7: /* object equality testing */
if (numargs != 2) goto argcerror;
leftint = (args[0] == args[1]);
goto return_boolean;
case 8: /* toggle debugging flag */
if (numargs == 0) {
debug = 1 - debug;
goto return_nil;
}
if (numargs != 2) goto argcerror;
if (! is_integer(args[0])) goto argterror;
if (! is_integer(args[1])) goto argterror;
leftint = int_value(args[0]);
rightint = int_value(args[1]);
switch(leftint) {
case 1: prntcmd = rightint; break;
case 2: debug = rightint; break;
}
goto return_nil;